import React, { useRef, useEffect, useState } from "react";
import { useSearchParams } from "react-router-dom";
import BpmnModeler from "bpmn-js/lib/Modeler";
import ProcessPropertiesPanel from  "@/components/ProcessPropertiesPanel"
import UserTask from  "@/components/ProcessPropertiesPanel/UserTask"
import Gateway from  "@/components/ProcessPropertiesPanel/Gateway"
import StartEvent from  "@/components/ProcessPropertiesPanel/StartEvent"
import EndEvent from  "@/components/ProcessPropertiesPanel/EndEvent"
import SequenceFlow from  "@/components/ProcessPropertiesPanel/SequenceFlow"


import ProcessTools from "@/components/ProcessTools/index.jsx";

import CustomPaletteProvider from '@/components/bpmn/platette2'
import CustomContextPadProvider from '@/components/bpmn/context-pad'
import { getProcessXml, deployment } from "@/api/definition";
import { xmlStr } from "@/mock/xmlStr";
import { message, Button,Drawer } from "antd";
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
import { useNavigate } from "react-router-dom";
import style from "./diagram.module.scss";
function Diagram() {
  const processEl = useRef(null);
  const userTaskRef = useRef(null);
  const gatewayRef = useRef(null);
  const startEventRef = useRef(null);
  const endEventRef = useRef(null);
  const sequenceFlowRef = useRef(null);
  const divEl = useRef(null);
  const [searchParams] = useSearchParams();
  const [xml] = React.useState(xmlStr);
  const [title, setTitle] = useState("流程");
  const [id] = useState(searchParams.get("id"));
  const [modeler, setModeler] = useState(null);
  const navigate = useNavigate();
  const [elementType, setElementType] = useState("");
  const [open, setOpen] = useState(true);
  const [placement] = useState('right');


  useEffect(() => {
    init();


    return () => {
      if(modeler && modeler.current) {
        modeler.destroy();
      }
    };


  }, []);

  const getProcessXmlById = async () => {
    if (!id) {
      return null;
    }
    let result = await getProcessXml(id);
    if (result.code === 200 && result.data && result.data.bpmnXml) {
      return result.data.bpmnXml;
    }
    return xml;
  };

  const callChild = (type, element,moder) => {
    switch (type) {
      case "bpmn:Process":
        setTitle("流程")
        processEl.current.callback(element,moder);
        break;
      case "bpmn:UserTask":
        setTitle("用户任务")
        userTaskRef.current.callback(element,moder);
        break;
      case "bpmn:ExclusiveGateway":
        setTitle("网关")
        gatewayRef.current.callback(element,moder);
        break;
        case "bpmn:StartEvent":
          setTitle("开始事件")
          startEventRef.current.callback(element,moder);
          break;
        case "bpmn:EndEvent":
          setTitle("结束事件")
          endEventRef.current.callback(element,moder);
          break;
      case "bpmn:SequenceFlow":
        setTitle("连接线")
        sequenceFlowRef.current.callback(element,moder);
        break;
      default:
        break;
    }
  };






  const init = () => {
    const modeler = new BpmnModeler({
      container: divEl.current,
      additionalModules: [CustomPaletteProvider,CustomContextPadProvider],
    });
    setModeler(modeler)
    getProcessXmlById().then(
      (processXml) => {
        createDiagram(modeler, processXml)
      },
      () => {
        message.error("获取流程xml失败");
        createDiagram(modeler,xmlStr);
      }
    );
  };



  const handElementClick = (event,currentModer) => {
    setElementType(event.element.type)
    setTimeout(() => {
      callChild(event.element.type, event.element,currentModer)
    },50)
  }


  // 注册图形事件
  const addEventListener = (modeler) => {
    const eventBus = modeler.get("eventBus");
    const eventTypes = ["element.click","element.changed"];
    eventTypes.forEach((eventType) => {
      eventBus.on(eventType, function (event) {
        if(eventType === "element.click") {
          handElementClick(event,modeler)
        }
        // 根节点不处理
      });
    });
  };


  // 注册画布渲染事件
  // const addRenderEventListener = (modeler) => {
  //   console.log("注册画布渲染事件");
  //   const eventTypes = ["shape.added", "shape.removed", "shape.move.end"];
  //   eventTypes.forEach((eventType) => {
  //     modeler.on(eventType, function (event) {
  //       console.log("画布渲染事件");
  //       console.log(event);
  //     });
  //   });
  // };

  const saveDiagram = () => {
    modeler.saveXML({ format: true }, (err, xml) => {
      if (err) {
        console.log(err);
      } else {
        let data = {
          processDefId: id,
          bpmnXml: xml,
        };
        // 部署流程
        deployment(data).then((res) => {
          if (res.code === 200) {
            navigate(-1);
            message.success("保存成功");
          }
        });
      }
    });
  };


  const initProcessPanel = (moder) =>{
    let elements = moder.get("elementRegistry")._elements;
    for(let key in elements){
      let element = elements[key].element;
      if(element.type === "bpmn:Process"){
        setElementType("bpmn:Process")
        processEl.current.callback(element,modeler)
      }
    }
  }






  const createDiagram = (modeler, xmlStr) => {
    modeler.importXML(xmlStr, (err) => {
      if (err) {
        console.log(err);
      } else {
        initProcessPanel(modeler)
        addEventListener(modeler);
      }
    });
  }

  const toggleDrawer = () => {
    setOpen(!open);
  };

  return (
    <>
      <div className={style.container}>
        <Button
            type="primary"
            icon={open ? <MenuFoldOutlined /> : <MenuUnfoldOutlined />} // 根据抽屉状态切换图标
            onClick={toggleDrawer}
            style={{
              position: 'fixed', // 固定定位
              right: open ? 378 : 0, // 固定在右侧
              top: '50%', // 垂直居中
              transform: 'translateY(-50%)', // 垂直居中
              zIndex: 1001, // 确保按钮在最上层
              transition: "right 0.3s",
            }}
        />
        <ProcessTools bpmnModeler={modeler} save={saveDiagram} />
        <Drawer
            title={title}
            placement={placement}
            closable={false}
            onClose={toggleDrawer}
            open={open}
            mask={false}
            key={placement}
            zIndex={1000}
        >
          <ProcessPropertiesPanel  ref={processEl}  type = {elementType} />
          <UserTask ref={userTaskRef}  type = {elementType}  />
          <Gateway ref={gatewayRef} type = {elementType}  />
          <StartEvent ref={startEventRef} type = {elementType}  />
          <EndEvent ref={endEventRef} type = {elementType}  />
          <SequenceFlow ref={sequenceFlowRef} type = {elementType}  />
        </Drawer>
        <div className={style.diagram} ref={divEl}></div>

      </div>
    </>
  );
}

export default Diagram;
